<?php

namespace App\Trip\Plane\Interfaces\Result\Abstracts;

use App\Facades\Plane\PlaneCompanySeedFacade;
use App\Models\Common\Area\Repositories\Interfaces\AreaRepositoryInterface;
use App\Models\Plane\Airports\Repositories\Interfaces\AirportRepositoryInterface;
use App\Trip\Plane\CarrierCode;
use App\Trip\Plane\Interfaces\Result\FlightQueryResultInterface;
use Illuminate\Support\Collection;

abstract class AbstractFlightQueryResult implements FlightQueryResultInterface
{

    /**
     * 页数 默认不分页
     * @return int
     */
    public function getPage(): int
    {
        return 1;
    }

    /**
     * 最后一页
     * @return int
     */
    public function getLastPage(): int
    {
        return ceil($this->getCount() / $this->getPageSize());
    }

    public function getCount(): int
    {
        return $this->getLists()->count();
    }

    /**
     * 航班列表
     * @return Collection
     */
    abstract public function getLists(): Collection;

    /**
     * 每页数量 默认不分页,等于总数量 具体类实现
     * @return int
     */
    public function getPageSize(): int
    {
        return $this->getCount();
    }

    public function getDepartTimes(): array
    {
        return config('trip.airplane.depart_times');
    }

    public function getCities(): array
    {
        $airportRepo = app(AirportRepositoryInterface::class);
        $areaRepo    = app(AreaRepositoryInterface::class);
        $from        = $this->getLists()->pluck('from_code')->unique()->map(function ($code) use ($airportRepo, $areaRepo) {
            $info = $airportRepo->findOneByCode($code);
            if (!$info) {
                return [];
            }
            $area = $areaRepo->findCityByCode($info->getAmapCityCode(), true);
            return [
                'city_code'    => $info->getPlaneCityCode(),
                'city_name'    => $area?->getAreaName(),
                'city_name_uy' => $area?->getAreaNameUy(),
                'adcode'       => $area?->getAdCode(),
            ];
        })->filter()->unique()->values()->toArray();
        $to          = $this->getLists()->pluck('to_code')->unique()->map(function ($code) use ($airportRepo, $areaRepo) {
            $info = $airportRepo->findOneByCode($code);
            if (!$info) {
                return [];
            }
            $area = $areaRepo->findCityByCode($info->getAmapCityCode(), true);
            return [
                'city_code'    => $info->getPlaneCityCode(),
                'city_name'    => $area?->getAreaName(),
                'city_name_uy' => $area?->getAreaNameUy(),
                'adcode'       => $area?->getAdCode(),
            ];
        })->filter()->unique()->values()->toArray();
        return compact('from', 'to');

    }

    public function getDepartAirports(): array
    {
        $airportRepo = app(AirportRepositoryInterface::class);
        return $this->getLists()->pluck('from_code')->unique()->map(function ($code) use ($airportRepo) {
            $info = $airportRepo->findOneByCode($code);
            if (!$info) {
                return [];
            }

            return [
                'airport_code'    => $info->getCode(),
                'airport_name'    => $info->getName(),
                'airport_name_uy' => $info->getNameUy(),
            ];
        })->values()->toArray();
    }

    public function getArriveAirports(): array
    {
        $airportRepo = app(AirportRepositoryInterface::class);
        return $this->getLists()->pluck('to_code')->unique()->map(function ($code) use ($airportRepo) {
            $info = $airportRepo->findOneByCode($code);
            if (!$info) {
                return [];
            }

            return [
                'airport_code'    => $info->getCode(),
                'airport_name'    => $info->getName(),
                'airport_name_uy' => $info->getNameUy(),
            ];
        })->values()->toArray();
    }

    public function getCompanies(): array
    {
        return $this->getLists()->pluck('flight_no')->map(function ($flight_no) {
            $c = CarrierCode::getCarrierCode($flight_no);
            return [
                'carrier_code'          => $c,
                'company_name'          => PlaneCompanySeedFacade::getCompanyNameByCode($c),
                'company_name_uy'       => PlaneCompanySeedFacade::getCompanyNameUyByCode($c),
                'company_short_name'    => PlaneCompanySeedFacade::getCompanyShortNameByCode($c),
                'company_short_name_uy' => PlaneCompanySeedFacade::getCompanyShortNameUyByCode($c),
            ];
        })->unique()->values()->toArray();
    }

    public function getPlaneTypes(): array
    {
        return $this->getLists()->map(function ($flight) {
            $name    = $flight['plane_type_name'];
            $name_uy = $flight['plane_type_name_uy'];
            return [
                'type'    => $flight['plane_type'],
                'name'    => $name,
                'name_uy' => $name_uy,
            ];
        })->unique('type')->values()->toArray();
    }
}